Infectious Diseases

Consider a simple disease that follows these simple rules:

  • if you have it, then you always have it
  • if you come "in contact" with someone who has it, then you get it

Sounds like zombies?

What would happen? How can we model this world?

Simulation

First, we must identify the objects we wish to model. Possibilities include:

  • people
  • world
  • disease

First, let's consider what properties a person should have:

  • position in the world
  • whether it is carrying the disease or not
  • direction heading (vector, velocity on x and y)

Also, what actions must a person be able to do:

  • move in the world
  • draw itself

We might want to add other methods, but it needs to at least support those.

Person

So, let's put together a person class. It might look something like:

class Person {
    int x;
    int y;
    int vx;
    int vy;
    int carrying; // zero - not carrying disease; 1 - carrying disease

    Person(int x, int y) {
        this.x = int(x);
        this.y = int(y);
        this.randomizeDirection();
        this.carrying = 0;
    }    
    ...
}

Like the termites, instead of having them bounce off of the walls (like a ball simulation) we will instead have them "wrap" around (like a torus). For example, if a person goes too far to the left, it will wrap around to the right, and instantly appear there. Likewise, if a turtle goes below 0 or above height, then it wraps back around. Thus, we implement an infinite, repeating surface.

This putting it all together might look like the following.

Note:

  • people are represented by ovals.
  • people turn green when they are infected
In [4]:
People [] person; // the array of people; we'll decide how many later
int RADIUS = 5; // distance that we can sense a wood chip

class Person {
    int x;
    int y;
    int vx;
    int vy;
    int carrying; // zero - not carrying disease; 1 - carrying disease
    
    Person(int x, int y) {
        this.x = int(x);
        this.y = int(y);
        this.randomizeDirection();
        this.carrying = 0;
    }
    
    void draw() {
        if (this.carrying == 0) {
            fill(128, 0, 0);
        } else {
            fill(0, 255, 0);
        }
        ellipse(this.x, this.y, 10, 10);
    }
    
    int get_x(int delta) {
        int dx = this.x + delta;
        if (dx >= width)
            dx -= width;
        if (dx < 0)
            dx += width;
        return dx;
    }
    
    int get_y(int delta) {
        int dy = this.y + delta;
        if (dy >= height)
            dy -= height;
        if (dy < 0)
            dy += height;
        return dy;
    }
    
    void step() {
        this.x = this.get_x(this.vx);
        this.y = this.get_y(this.vy);
    }
    
    void randomizeDirection() {
        this.vx = 0;
        this.vy = 0;
        while (this.vx == 0 && this.vy == 0) {
            this.vx = floor(random(3)) - 1;
            this.vy = floor(random(3)) - 1;
        }
    }
    
    float distance(Person person) {
        return sqrt( pow(this.x - person.x, 2) + pow(this.y - person.y, 2)); 
    }
    
    void move() {
        if (this.carrying == 1) {
            if (random() < 1.0) { // 10% of the time, change directions
                this.randomizeDirection();
            }
        } else {
            if (random() < .01) { // 10% of the time, change directions
                this.randomizeDirection();
            }
        }
        this.step();
        // carrying a disease
        if (this.carrying == 1) { 
            // find people within radius, and infect them
            // some percentage of time
            for (int p = 0; p < people.length; p++) {
                if (this.distance(people[p]) < RADIUS) {
                    people[p].carrying = 1;
                }
            }
        } 
    }
}

void setup() {
    size(500, 250); // the world
    people = new Person[500]; // start termites
    for (int i =0; i < people.length; i++) {
        people[i] = new Person(random(width), random(height));
    }
    // How many to infect initially?
    people[0].carrying = 1;
}

void draw() {
    background();
    noStroke();
    // Move the termites:
    for (int i =0; i < people.length; i++) {
        people[i].move();
        people[i].draw();
    }    
}
Sketch #4:

Sketch #4 state: Loading...